#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../src/bscpoll.h"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <Windows.h>
#endif


char *host = "192.168.1.10", *port = "11300", errorstr[BSC_ERRSTR_LEN];
static bsc_error_t bsc_error;
static int reconnect_attempts = 5, finished = 0;
uint64_t reserve_id;
char* reserve_str = NULL;
int reserve_len = 0;

void reply_cb(bsc *client , struct bsc_reply_info * info) {
    finished = true;
}

void reserve_cb(bsc *client, struct bsc_reserve_info *info)
{
    printf("got reserve %llu %s\n", info->response.id,(const char*)info->response.data);
	if (info->response.code == BSC_RESERVE_RES_RESERVED) {
		reserve_str = realloc(reserve_str,info->response.bytes+1);
		reserve_len = info->response.bytes+1;
		strncpy(reserve_str, info->response.data, info->response.bytes);
		reserve_id = info->response.id;
	}
	else {
		reserve_id = 0;
	}
	finished = true;
}


static void reconnect(bsc *client, bsc_error_t error)
{
    char errorstr[BSC_ERRSTR_LEN];
    int i;

    switch (error) {
        case BSC_ERROR_INTERNAL:
            fprintf(stderr, "critical error: recieved BSC_ERROR_INTERNAL, quitting\n");
            break;
        case BSC_ERROR_MEMORY:
            fprintf(stderr, "critical error: recieved BSC_ERROR_MEMORY, quitting\n");
            break;
        case BSC_ERROR_SOCKET:
            fprintf(stderr, "error: recieved BSC_ERROR_SOCKET, attempting to reconnect ...\n");
						--reconnect_attempts;
						bsc_connect_async(client, errorstr);
            fprintf(stderr, "error: reconnect attempt %d ", reconnect_attempts);
            break;
        default:
            fprintf(stderr, "critical error: got unknown error (%d)\n", error);
    }

		if(reconnect_attempts==0)
			exit(EXIT_FAILURE);
}

static void onconnect(bsc *client) {
	finished = true;
}

#define WAIT_FINISH \
	finished = false; \
	while (!finished) {\
		if (bscpoll_wait(poll,5000) == EXIT_FAILURE)\
			return EXIT_FAILURE;\
	}\




int main(int argc, char **argv)
{
	bsc_poll* poll;
	bsc *client;

#ifdef _WIN32
	WSADATA ws;
	WSAStartup(MAKEWORD(2, 2), &ws);
#endif

	poll = create_bscpoll();

	client = bsc_new_async(host, port, "default", reconnect, onconnect,16, 12, 4, errorstr);
	if(!client) {
		fprintf(stderr, "bsc_new: %s", errorstr);
		return EXIT_FAILURE;
	}

	bscpoll_add(poll, client);
	WAIT_FINISH;

	while (1) {
		finished = false;

		bsc_error = bsc_reserve(client, reserve_cb, NULL, BSC_RESERVE_NO_TIMEOUT);
		if (bsc_error != BSC_ERROR_NONE)
			fprintf(stderr, "bsc_reserve failed (%d)", bsc_error);

		WAIT_FINISH;

		finished = false;
		bsc_reply(client, reply_cb, NULL, reserve_id, reserve_len, reserve_str, false);

		WAIT_FINISH;
	}

	bsc_free(client);
	destroy_bscpoll(poll);
	free(reserve_str);
}
